package com.wlz.service.impl;

import com.wlz.dao.AccountInfoDao;
import com.wlz.dao.ProductInfoDao;
import com.wlz.service.PayService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * @author wlz
 * @date 2022-06-01  9:39 下午
 */

@Service
public class PayServiceImpl implements PayService {

	@Autowired
	private AccountInfoDao accountInfoDao;

	@Autowired
	private ProductInfoDao productInfoDao;

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void pay(String accountId, double money) {

		// 查询 余额
		double blance = accountInfoDao.qryBlanceByUserId(accountId);

		// 余额不足
		if (new BigDecimal(blance).compareTo(new BigDecimal(money)) < 0) {
			throw new RuntimeException("余额不足");
		}

		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		// 这样调用 是事务 在 内部方法调用 进行传播
		((PayService) AopContext.currentProxy()).updateProductStore(1);

		int i = 1/0;

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void updateProductStore(Integer productId) {

		try {
			productInfoDao.updateProductInfo(productId);
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}

	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationRequired(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

//		int i = 1/0;

		try {
			// 这样调用 是事务 在 内部方法调用 进行传播
			((PayService) AopContext.currentProxy()).updateProductStorePropagationRequired(1);
		} catch (Exception e) {
			e.printStackTrace();
		}

//		int i = 1/0;
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void updateProductStorePropagationRequired(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationSupports(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

//		int i = 1/0;

		// 这样调用 是事务 在 内部方法调用 进行传播
		((PayService) AopContext.currentProxy()).updateProductStorePropagationSupports(1);

//		int i = 1/0;
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
	@Override
	public void updateProductStorePropagationSupports(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);

			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationMandatory(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		// 这样调用 是事务 在 内部方法调用 进行传播
		((PayService) AopContext.currentProxy()).updateProductStorePropagationMandatory(1);

	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
	@Override
	public void updateProductStorePropagationMandatory(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationRequiresNew(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		// 异常捕获
//		try {
			// 这样调用 是事务 在 内部方法调用 进行传播
			((PayService) AopContext.currentProxy()).updateProductStorePropagationRequiresNew(1);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

		int i = 1/0;
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
	@Override
	public void updateProductStorePropagationRequiresNew(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
//			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationNotSupported(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		// 这样调用 是事务 在 内部方法调用 进行传播
		((PayService) AopContext.currentProxy()).updateProductStorePropagationNotSupported(1);

	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
	@Override
	public void updateProductStorePropagationNotSupported(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationNever(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		// 这样调用 是事务 在 内部方法调用 进行传播
		((PayService) AopContext.currentProxy()).updateProductStorePropagationNever(1);

	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.NEVER)
	@Override
	public void updateProductStorePropagationNever(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
	@Override
	public void payPropagationNested(String accountId, double money) {
		// 更新余额
		int retVal = accountInfoDao.updateAccountBlance(accountId,money);
		System.out.println( "retVal: " + retVal);

		try {
			// 这样调用 是事务 在 内部方法调用 进行传播
			((PayService) AopContext.currentProxy()).updateProductStorePropagationNested(1);
		} catch (Exception e) {
			e.printStackTrace();
		}

//		int i = 1/0;
	}

	@SuppressWarnings("divzero")
	@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
	@Override
	public void updateProductStorePropagationNested(Integer productId) {
		try {
			productInfoDao.updateProductInfo(productId);
			int i = 1/0;
		}catch (Exception e) {
			throw new RuntimeException("内部异常");
		}
	}
}
